//+------------------------------------------------------------------+
//|                                                PrecisionEA.mq5   |
//|                                    Copyright 2024, Precision EA  |
//+------------------------------------------------------------------+
#property copyright "Copyright 2024, Precision EA"
#property link      "https://www.precision-ea.com"
#property version   "4.0"
#property strict

#include "TradeOrchestrator.mqh"

//+------------------------------------------------------------------+
//| Inputs                                                          |
//+------------------------------------------------------------------+
input string   GeneralSettings = "=== General Settings ===";
input bool     EnableAutoTrading = true;
input bool     EnableLogging = true;
input bool     EnableDebugMode = false;
input int      SignalCheckInterval = 60; // Seconds

input string   SignalSettings = "=== Signal Settings ===";
input double   MinSignalConfidence = 0.6;
input double   MaxATRThreshold = 0.015;
input double   MinATRThreshold = 0.002;
input int      PullbackTolerance = 30;
input double   RiskRewardRatio = 1.5;

input string   RiskSettings = "=== Risk Settings ===";
input double   MaxPositionRisk = 0.01;      // 1% per trade
input double   DailyDrawdownLimit = 0.03;   // 3% daily
input double   GlobalDrawdownLimit = 0.05;  // 5% global
input int      MaxConsecutiveLosses = 3;
input double   DailyProfitTarget = 0.02;    // 2% target
input double   DailyLossLimit = 0.02;       // 2% limit
input int      MaxDailyTrades = 5;
input int      MaxPositions = 1;
input double   MinRewardRatio = 1.5;

input string   ExecutionSettings = "=== Execution Settings ===";
input double   SlippagePoints = 3.0;
input bool     UseStopLoss = true;
input bool     UseTakeProfit = true;
input int      MaxRetries = 3;
input int      RetryDelayMs = 100;
input double   MaxSpreadPoints = 30.0;

//+------------------------------------------------------------------+
//| Global Variables                                                |
//+------------------------------------------------------------------+
TradeOrchestrator *orchestrator = NULL;
datetime last_chart_update = 0;
int chart_update_interval = 1; // Seconds

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit() {
    Logger::Initialize(Symbol(), 
        EnableDebugMode ? LOG_LEVEL_DEBUG : LOG_LEVEL_INFO,
        EnableLogging,
        true);
    
    Logger::Info("=== PRECISION EA v4.0 INITIALIZATION ===", "SYSTEM");
    
    // Check trading permissions
    if(!TerminalInfoInteger(TERMINAL_TRADE_ALLOWED)) {
        Logger::Critical("Terminal trading is disabled", "SYSTEM");
        return INIT_FAILED;
    }
    
    if(!MQLInfoInteger(MQL_TRADE_ALLOWED)) {
        Logger::Critical("EA trading is disabled in settings", "SYSTEM");
        return INIT_FAILED;
    }
    
    if(!SymbolInfoInteger(Symbol(), SYMBOL_TRADE_MODE)) {
        Logger::Critical("Symbol trading is disabled", "SYSTEM");
        return INIT_FAILED;
    }
    
    // Check account limitations
    if(AccountInfoInteger(ACCOUNT_LIMIT_ORDERS) == 0) {
        Logger::Warn("Account has order limits", "SYSTEM");
    }
    
    // Create orchestrator
    orchestrator = new TradeOrchestrator(Symbol());
    
    if(orchestrator == NULL) {
        Logger::Critical("Failed to create orchestrator", "SYSTEM");
        return INIT_FAILED;
    }
    
    // Initialize orchestrator
    if(!orchestrator->Initialize()) {
        Logger::Critical("Failed to initialize orchestrator", "SYSTEM");
        delete orchestrator;
        orchestrator = NULL;
        return INIT_FAILED;
    }
    
    // Start orchestrator if auto trading is enabled
    if(EnableAutoTrading) {
        orchestrator->Start();
    } else {
        orchestrator->Pause();
    }
    
    // Display configuration
    Logger::Info("=== CONFIGURATION ===", "SYSTEM");
    Logger::Info(StringFormat("Symbol: %s (%s)", 
        Symbol(), EnumToString((ENUM_TIMEFRAMES)Period())), "SYSTEM");
    Logger::Info(StringFormat("Auto Trading: %s", 
        EnableAutoTrading ? "ENABLED" : "DISABLED"), "SYSTEM");
    Logger::Info(StringFormat("Risk per Trade: %.2f%%", MaxPositionRisk * 100), "SYSTEM");
    Logger::Info(StringFormat("Daily Loss Limit: %.2f%%", DailyLossLimit * 100), "SYSTEM");
    Logger::Info("=========================", "SYSTEM");
    
    // Create chart objects
    CreateChartObjects();
    
    Logger::Info("EA successfully initialized", "SYSTEM");
    return INIT_SUCCEEDED;
}

//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason) {
    Logger::Info("=== EA DEINITIALIZATION ===", "SYSTEM");
    
    // Display final report
    if(orchestrator != NULL) {
        orchestrator->PrintStatus();
        
        // Close positions if EA is being removed
        if(reason == REASON_REMOVE || reason == REASON_CLOSE) {
            Logger::Info("Closing all positions...", "SYSTEM");
            Sleep(1000); // Give time for logging
        }
        
        // Stop and delete orchestrator
        orchestrator->Stop();
        delete orchestrator;
        orchestrator = NULL;
    }
    
    // Remove chart objects
    RemoveChartObjects();
    
    Logger::Info(StringFormat("EA detached (Reason: %s)", GetUninitReasonText(reason)), "SYSTEM");
    Logger::Info("==============================", "SYSTEM");
}

//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick() {
    if(orchestrator == NULL) return;
    
    // Process orchestrator logic
    orchestrator->OnTick();
    
    // Update chart display
    datetime now = TimeCurrent();
    if(now - last_chart_update >= chart_update_interval) {
        UpdateChart();
        last_chart_update = now;
    }
}

//+------------------------------------------------------------------+
//| Timer function (if needed)                                       |
//+------------------------------------------------------------------+
void OnTimer() {
    // Optional: Add timer-based operations here
}

//+------------------------------------------------------------------+
//| Chart event handler                                              |
//+------------------------------------------------------------------+
void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam) {
    // Handle chart events (clicks, etc.)
    if(id == CHARTEVENT_OBJECT_CLICK) {
        string clicked = sparam;
        
        if(clicked == "btn_emergency_stop") {
            if(orchestrator != NULL) {
                orchestrator->EmergencyStop();
                ObjectSetString(0, "btn_emergency_stop", OBJPROP_TEXT, "EMERGENCY STOPPED");
                ObjectSetInteger(0, "btn_emergency_stop", OBJPROP_BGCOLOR, clrRed);
            }
        }
        else if(clicked == "btn_pause_resume") {
            if(orchestrator != NULL) {
                if(orchestrator->IsAutoTrading()) {
                    orchestrator->Pause();
                    ObjectSetString(0, "btn_pause_resume", OBJPROP_TEXT, "RESUME");
                    ObjectSetInteger(0, "btn_pause_resume", OBJPROP_BGCOLOR, clrGray);
                } else {
                    orchestrator->Resume();
                    ObjectSetString(0, "btn_pause_resume", OBJPROP_TEXT, "PAUSE");
                    ObjectSetInteger(0, "btn_pause_resume", OBJPROP_BGCOLOR, clrYellow);
                }
            }
        }
    }
}

//+------------------------------------------------------------------+
//| Create chart objects for control                                 |
//+------------------------------------------------------------------+
void CreateChartObjects() {
    // Remove any existing objects
    RemoveChartObjects();
    
    // Create emergency stop button
    ObjectCreate(0, "btn_emergency_stop", OBJ_BUTTON, 0, 0, 0);
    ObjectSetInteger(0, "btn_emergency_stop", OBJPROP_XDISTANCE, 10);
    ObjectSetInteger(0, "btn_emergency_stop", OBJPROP_YDISTANCE, 30);
    ObjectSetInteger(0, "btn_emergency_stop", OBJPROP_XSIZE, 100);
    ObjectSetInteger(0, "btn_emergency_stop", OBJPROP_YSIZE, 30);
    ObjectSetString(0, "btn_emergency_stop", OBJPROP_TEXT, "EMERGENCY STOP");
    ObjectSetInteger(0, "btn_emergency_stop", OBJPROP_BGCOLOR, clrOrangeRed);
    ObjectSetInteger(0, "btn_emergency_stop", OBJPROP_COLOR, clrWhite);
    ObjectSetInteger(0, "btn_emergency_stop", OBJPROP_FONTSIZE, 10);
    
    // Create pause/resume button
    ObjectCreate(0, "btn_pause_resume", OBJ_BUTTON, 0, 0, 0);
    ObjectSetInteger(0, "btn_pause_resume", OBJPROP_XDISTANCE, 120);
    ObjectSetInteger(0, "btn_pause_resume", OBJPROP_YDISTANCE, 30);
    ObjectSetInteger(0, "btn_pause_resume", OBJPROP_XSIZE, 100);
    ObjectSetInteger(0, "btn_pause_resume", OBJPROP_YSIZE, 30);
    ObjectSetString(0, "btn_pause_resume", OBJPROP_TEXT, EnableAutoTrading ? "PAUSE" : "RESUME");
    ObjectSetInteger(0, "btn_pause_resume", OBJPROP_BGCOLOR, EnableAutoTrading ? clrYellow : clrGray);
    ObjectSetInteger(0, "btn_pause_resume", OBJPROP_COLOR, clrBlack);
    ObjectSetInteger(0, "btn_pause_resume", OBJPROP_FONTSIZE, 10);
    
    // Create info panel
    ObjectCreate(0, "info_panel", OBJ_RECTANGLE_LABEL, 0, 0, 0);
    ObjectSetInteger(0, "info_panel", OBJPROP_XDISTANCE, 10);
    ObjectSetInteger(0, "info_panel", OBJPROP_YDISTANCE, 70);
    ObjectSetInteger(0, "info_panel", OBJPROP_XSIZE, 210);
    ObjectSetInteger(0, "info_panel", OBJPROP_YSIZE, 150);
    ObjectSetInteger(0, "info_panel", OBJPROP_BGCOLOR, clrBlack);
    ObjectSetInteger(0, "info_panel", OBJPROP_BORDER_TYPE, BORDER_FLAT);
    ObjectSetInteger(0, "info_panel", OBJPROP_BORDER_COLOR, clrGray);
}

//+------------------------------------------------------------------+
//| Remove chart objects                                             |
//+------------------------------------------------------------------+
void RemoveChartObjects() {
    ObjectDelete(0, "btn_emergency_stop");
    ObjectDelete(0, "btn_pause_resume");
    ObjectDelete(0, "info_panel");
    ObjectDelete(0, "info_text");
}

//+------------------------------------------------------------------+
//| Update chart display                                             |
//+------------------------------------------------------------------+
void UpdateChart() {
    if(orchestrator == NULL) return;
    
    string info_text = "PRECISION EA v4.0\n";
    info_text += "====================\n";
    info_text += "Symbol: " + Symbol() + "\n";
    info_text += "Time: " + TimeToString(TimeCurrent(), TIME_MINUTES|TIME_SECONDS) + "\n";
    info_text += "Status: " + string(orchestrator->IsRunning() ? "RUNNING" : "STOPPED") + "\n";
    info_text += "Auto: " + string(orchestrator->IsAutoTrading() ? "ON" : "OFF") + "\n";
    
    // Add signal info
    GoldSignalGenerator* signal_gen = orchestrator->GetSignalGenerator();
    if(signal_gen != NULL) {
        info_text += "\nSignal Info:\n";
        info_text += "Price: " + DoubleToString(signal_gen->GetCurrentPrice(), 2) + "\n";
        info_text += "ATR: " + DoubleToString(signal_gen->GetCurrentATR(), 2) + "\n";
    }
    
    // Add risk info
    RiskManager* risk_mgr = orchestrator->GetRiskManager();
    if(risk_mgr != NULL) {
        info_text += "\nRisk Status:\n";
        info_text += "Allowed: " + string(risk_mgr->IsTradingAllowed() ? "YES" : "NO") + "\n";
        info_text += "Daily Trades: " + IntegerToString(risk_mgr->GetDailyTrades()) + "\n";
        info_text += "Drawdown: " + DoubleToString(risk_mgr->GetDrawdown(), 2) + "%\n";
    }
    
    // Create or update info text object
    if(ObjectFind(0, "info_text") < 0) {
        ObjectCreate(0, "info_text", OBJ_LABEL, 0, 0, 0);
        ObjectSetInteger(0, "info_text", OBJPROP_XDISTANCE, 15);
        ObjectSetInteger(0, "info_text", OBJPROP_YDISTANCE, 75);
        ObjectSetInteger(0, "info_text", OBJPROP_CORNER, CORNER_LEFT_UPPER);
        ObjectSetInteger(0, "info_text", OBJPROP_COLOR, clrWhite);
        ObjectSetInteger(0, "info_text", OBJPROP_FONTSIZE, 8);
    }
    
    ObjectSetString(0, "info_text", OBJPROP_TEXT, info_text);
}

//+------------------------------------------------------------------+
//| Utility functions                                               |
//+------------------------------------------------------------------+
string GetUninitReasonText(int reason) {
    switch(reason) {
        case REASON_ACCOUNT:     return "Account changed";
        case REASON_CHARTCHANGE: return "Symbol/timeframe changed";
        case REASON_CHARTCLOSE:  return "Chart closed";
        case REASON_CLOSE:       return "Terminal closed";
        case REASON_INITFAILED:  return "Initialization failed";
        case REASON_PARAMETERS:  return "Parameters changed";
        case REASON_RECOMPILE:   return "Recompiled";
        case REASON_REMOVE:      return "EA removed";
        case REASON_TEMPLATE:    return "Template changed";
        default:                 return "Unknown";
    }
}

//+------------------------------------------------------------------+